package com.winit.schedule.webc.support;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import com.winit.schedule.webc.annotation.Controller;
import com.winit.schedule.webc.annotation.RequestMapping;
import com.winit.schedule.webc.exception.ScheduleWebcException;
import com.winit.schedule.webc.util.Constants;
import com.winit.schedule.webc.util.StringUtils;

public class DefaultControllerParser implements ControllerParser {

    public DefaultControllerParser(){
    }

    @Override
    public ControllerDelegate parse(Object controller) {
        Controller ctrl = controller.getClass().getAnnotation(Controller.class);
        if (null != ctrl) {
            String namespace = ctrl.value();
            if (StringUtils.isBlank(namespace)) {
                namespace = Constants.DEFAULT_NAMESPACE;
            }
            ControllerDelegate delegate = new ControllerDelegate(namespace, controller);
            parseMethodMapping(delegate);
            return delegate;

        } else {
            throw new ScheduleWebcException("Failed to register Controller, Did not add annotation.");
        }
    }

    private void parseMethodMapping(ControllerDelegate delegate) {
        Object obj = delegate.getController();
        Method[] methods = obj.getClass().getDeclaredMethods();

        Map<String, MethodMapping> mappings = new HashMap<String, MethodMapping>();
        MethodMapping methodMapping = null;
        for (Method method : methods) {
            if (Modifier.isPublic(method.getModifiers())) {
                RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                if (null != mapping) {
                    String requestMapping = mapping.value();
                    if (!mappings.containsKey(requestMapping)) {
                        methodMapping = new MethodMapping(requestMapping, mapping.responseTyte(), method, delegate);
                        mappings.put(requestMapping, methodMapping);
                    }
                }

            }
        }
        delegate.setMethodMappings(mappings);
    }
}
